home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / toolmanager.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  16KB  |  545 lines

  1. /*
  2.  * toolmanager.c  V3.1
  3.  *
  4.  * Preferences editor main entry point
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local function prototypes */
  19. static int Preferences(void);
  20.  
  21. /* Entry point (first in code hunk) */
  22. static __geta4 int Entry(void)
  23. {
  24.  /* Initialize SysBase */
  25.  SysBase = *((struct Library **) 4);
  26.  
  27.  /* Call the real code */
  28.  return(Preferences());
  29. }
  30.  
  31. /* Version string */
  32. static const char Version[] = "$VER: ToolManager " TMVERSION
  33.                               " (" __COMMODORE_DATE__ ")";
  34.  
  35. /* Error requester */
  36. static const struct EasyStruct ErrorRequester = {
  37.  sizeof(struct EasyStruct), 0, "ToolManager Preferences",
  38.  "Program initialization failed!", "OK"
  39. };
  40.  
  41. /* CLI command line parameters */
  42. static const char Template[] = "FROM,EDIT/S,USE/S,SAVE/S,CREATEICONS/S";
  43. static struct {
  44.  char *From;
  45.  LONG  Edit;
  46.  LONG  Use;
  47.  LONG  Save;
  48.  LONG  Icons;
  49. } CmdLineParameters = { NULL, TRUE, FALSE, FALSE, FALSE};
  50.  
  51. /* Structure for stack swap */
  52. #define STACKSIZE 8192 /* Minimum for MUI applications */
  53. static struct StackSwapStruct MUIStack = { NULL, NULL, NULL };
  54.  
  55. /* Global data */
  56. struct Library         *DOSBase                   = NULL;
  57. struct Library         *IconBase                  = NULL;
  58. struct Library         *IFFParseBase              = NULL;
  59. struct Library         *IntuitionBase             = NULL;
  60. struct Library         *MUIMasterBase             = NULL;
  61. struct Library         *SysBase                   = NULL;
  62. struct Library         *UtilityBase               = NULL;
  63. struct MUI_CustomClass *MainWindowClass           = NULL;
  64. struct MUI_CustomClass *GlobalClass               = NULL;
  65. struct MUI_CustomClass *ListPanelClass            = NULL;
  66. struct MUI_CustomClass *ListTreeClass             = NULL;
  67. struct MUI_CustomClass *PopASLClass               = NULL;
  68. struct MUI_CustomClass *DropAreaClass             = NULL;
  69. struct MUI_CustomClass *EntryListClass            = NULL;
  70. struct MUI_CustomClass *BaseClass                 = NULL;
  71. struct MUI_CustomClass *ObjectClasses[TMOBJTYPES] = { NULL, NULL, NULL, NULL,
  72.                                                       NULL, NULL, NULL };
  73. struct MUI_CustomClass *GroupClass                = NULL;
  74. struct MUI_CustomClass *ClipWindowClass           = NULL;
  75. struct MUI_CustomClass *ClipListClass             = NULL;
  76. char                   *ProgramName               = NULL;
  77. ULONG                   CreateIcons               = TRUE;
  78. const char              ConfigSaveName[]          = "ENVARC:" TMCONFIGNAME;
  79. const char              ConfigUseName[]           = "ENV:"    TMCONFIGNAME;
  80.  
  81. /* AppMessage function */
  82. #undef  DEBUGFUNCTION
  83. #define DEBUGFUNCTION AppMessageFunction
  84. __geta4 static ULONG AppMessageFunction(__a0 struct Hook *h,
  85.                                         __a1 struct AppMessage **amp,
  86.                                         __a2 Object *obj)
  87. {
  88.  /* Send AppEvent method to MainWindow */
  89.  DoMethod(h->h_Data, TMM_AppEvent, *amp, obj);
  90. }
  91.  
  92. /* Hook */
  93. struct Hook AppMessageHook = {
  94.  {NULL, NULL}, (void *) AppMessageFunction, NULL, NULL
  95. };
  96.  
  97. /* Open minimum set of Libraries */
  98. static BOOL OpenLibraries(void)
  99. {
  100.  return((DOSBase       = OpenLibrary("dos.library",       39)) &&
  101.         (IconBase      = OpenLibrary("icon.library",      39)) &&
  102.         (IntuitionBase = OpenLibrary("intuition.library", 39)));
  103. }
  104.  
  105. /* Close libraries */
  106. static void CloseLibraries(void)
  107. {
  108.  if (IntuitionBase) CloseLibrary(IntuitionBase);
  109.  if (IconBase)      CloseLibrary(IconBase);
  110.  if (DOSBase)       CloseLibrary(DOSBase);
  111. }
  112.  
  113. /* Allocate full set of resources */
  114. static BOOL GetEditResources(void)
  115. {
  116.  return(/* Libraries */
  117.         (IFFParseBase  = OpenLibrary("iffparse.library",  39)) &&
  118.         (MUIMasterBase = OpenLibrary("muimaster.library", 18)) &&
  119.         (UtilityBase   = OpenLibrary("utility.library",   39)) &&
  120.  
  121.         /* Memory management */
  122.         InitMemory() &&
  123.  
  124.         /* Classes */
  125.         (MainWindowClass                 = CreateMainWindowClass()) &&
  126.         (GlobalClass                     = CreateGlobalClass())     &&
  127.         (ListPanelClass                  = CreateListPanelClass())  &&
  128.         (ListTreeClass                   = CreateListTreeClass())   &&
  129.         (PopASLClass                     = CreatePopASLClass())     &&
  130.         (DropAreaClass                   = CreateDropAreaClass())   &&
  131.         (EntryListClass                  = CreateEntryListClass())  &&
  132.         (BaseClass                       = CreateBaseClass())       &&
  133.         (ObjectClasses[TMOBJTYPE_EXEC]   = CreateExecClass())       &&
  134.         (ObjectClasses[TMOBJTYPE_IMAGE]  = CreateImageClass())      &&
  135.         (ObjectClasses[TMOBJTYPE_SOUND]  = CreateSoundClass())      &&
  136.         (ObjectClasses[TMOBJTYPE_MENU]   = CreateMenuClass())       &&
  137.         (ObjectClasses[TMOBJTYPE_ICON]   = CreateIconClass())       &&
  138.         (ObjectClasses[TMOBJTYPE_DOCK]   = CreateDockClass())       &&
  139.         (ObjectClasses[TMOBJTYPE_ACCESS] = CreateAccessClass())     &&
  140.         (GroupClass                      = CreateGroupClass())      &&
  141.         (ClipWindowClass                 = CreateClipWindowClass()) &&
  142.         (ClipListClass                   = CreateClipListClass())
  143.        );
  144. }
  145.  
  146. /* Free resources */
  147. static void FreeEditResources(void)
  148. {
  149.  int i;
  150.  
  151.  /* Free global data */
  152.  FreeGlobalData();
  153.  
  154.  /* Classes */
  155.  if (ClipListClass)     MUI_DeleteCustomClass(ClipListClass);
  156.  if (ClipWindowClass)   MUI_DeleteCustomClass(ClipWindowClass);
  157.  if (GroupClass)        MUI_DeleteCustomClass(GroupClass);
  158.  for (i = TMOBJTYPE_ACCESS; i >= TMOBJTYPE_EXEC; i--)
  159.   if (ObjectClasses[i]) MUI_DeleteCustomClass(ObjectClasses[i]);
  160.  if (BaseClass)         MUI_DeleteCustomClass(BaseClass);
  161.  if (EntryListClass)    MUI_DeleteCustomClass(EntryListClass);
  162.  if (DropAreaClass)     MUI_DeleteCustomClass(DropAreaClass);
  163.  if (PopASLClass)       MUI_DeleteCustomClass(PopASLClass);
  164.  if (ListTreeClass)     MUI_DeleteCustomClass(ListTreeClass);
  165.  if (ListPanelClass)    MUI_DeleteCustomClass(ListPanelClass);
  166.  if (GlobalClass)       MUI_DeleteCustomClass(GlobalClass);
  167.  if (MainWindowClass)   MUI_DeleteCustomClass(MainWindowClass);
  168.  
  169.  /* Memory management */
  170.  DeleteMemory();
  171.  
  172.  /* Libraries */
  173.  if (UtilityBase)   CloseLibrary(UtilityBase);
  174.  if (MUIMasterBase) CloseLibrary(MUIMasterBase);
  175.  if (IFFParseBase)  CloseLibrary(IFFParseBase);
  176. }
  177.  
  178. /* Create program name from Workbench arguments */
  179. static char *CreateProgramName(struct WBArg *wa)
  180. {
  181.  char *rc;
  182.  
  183.  /* Get memory for buffer */
  184.  if (rc = GetVector(LENGTH_FILENAME))
  185.  
  186.   /* Workbench or CLI startup? */
  187.   if ((wa ?
  188.  
  189.   /* Workbench, convert directory lock and add name */
  190.             (NameFromLock(wa->wa_Lock, rc, LENGTH_FILENAME) &&
  191.              AddPart(rc, wa->wa_Name, LENGTH_FILENAME)) :
  192.  
  193.   /* CLI, copy program name to buffer */
  194.             GetProgramName(rc, LENGTH_FILENAME)) == FALSE) {
  195.  
  196.    /* Error, free buffer */
  197.    FreeVector(rc);
  198.    rc = NULL;
  199.   }
  200.  
  201.  return(rc);
  202. }
  203.  
  204. /* Copy configuration file */
  205. #undef  DEBUGFUNCTION
  206. #define DEBUGFUNCTION CopyFile
  207. static int CopyFile(const char *source, const char *dest)
  208. {
  209.  void *buffer;
  210.  int   rc     = RETURN_FAIL;
  211.  
  212.  STARTUP_LOG(LOG2(Arguments, "Source %s Dest %s", source, dest))
  213.  
  214.  /* Allocate copy buffer */
  215.  if (buffer = AllocMem(4096, MEMF_PUBLIC)) {
  216.   BPTR in;
  217.  
  218.   STARTUP_LOG(LOG1(Buffer, "0x%08lx", buffer))
  219.  
  220.   /* Open source file */
  221.   if (in = Open(source, MODE_OLDFILE)) {
  222.    BPTR out;
  223.  
  224.    STARTUP_LOG(LOG1(Input, "0x%08lx", in))
  225.  
  226.    /* Open destination file */
  227.    if (out = Open(dest, MODE_NEWFILE)) {
  228.     LONG n;
  229.  
  230.     STARTUP_LOG(LOG1(Ouput, "0x%08lx", out))
  231.  
  232.     /* Copy file, read one block from source and write it to dest */
  233.     while (((n = Read(in, buffer, 4096)) > 0) && (Write(out, buffer, n) == n));
  234.  
  235.     /* All bytes copied, that is the last read returned 0? */
  236.     if (n == 0) rc = RETURN_OK;
  237.  
  238.     /* Close destination file */
  239.     Close(out);
  240.    }
  241.  
  242.    /* Close source file */
  243.    Close(in);
  244.   }
  245.  
  246.   /* Free copy buffer */
  247.   FreeMem(buffer, 4096);
  248.  }
  249.  
  250.  STARTUP_LOG(LOG1(Result, "%ld", rc))
  251.  
  252.  return(rc);
  253. }
  254.  
  255. /* Main entry point */
  256. #undef  DEBUGFUNCTION
  257. #define DEBUGFUNCTION main
  258. static int Preferences(void)
  259. {
  260.  struct WBStartup *wbs = NULL;
  261.  struct Process   *pr  = (struct Process *) FindTask(NULL);
  262.  int               rc  = RETURN_FAIL;
  263.  
  264.  /* Started from CLI or Workbench? */
  265.  if (pr->pr_CLI == NULL) {
  266.  
  267.   /* Started from Workbench, wait for startup message */
  268.   WaitPort(&pr->pr_MsgPort);
  269.  
  270.   /* Retrieve message */
  271.   wbs = (struct WBStartup *) GetMsg(&pr->pr_MsgPort);
  272.  }
  273.  
  274.  /* Initialize debugging */
  275.  INITDEBUG(ToolManagerPrefsDebug)
  276.  
  277.  /* Open minimum set of libraries */
  278.  if (OpenLibraries()) {
  279.   struct RDArgs     *rda    = NULL;
  280.   BPTR               oldcd;
  281.   struct DiskObject *dobj   = NULL;
  282.   const char        *config = ConfigUseName;
  283.   BOOL               edit   = FALSE;
  284.  
  285.   STARTUP_LOG(LOG0(Libraries opened))
  286.  
  287.   /* CLI or WB startup? */
  288.   if (wbs) {
  289.  
  290.    /* Go to program directory */
  291.    oldcd = CurrentDir(wbs->sm_ArgList->wa_Lock);
  292.  
  293.    /* Open program icon */
  294.    if (dobj = GetDiskObject(wbs->sm_ArgList->wa_Name)) {
  295.     char *value;
  296.  
  297.     /* Check for CREATEICONS tool type */
  298.     if (value = FindToolType(dobj->do_ToolTypes, "CREATEICONS"))
  299.  
  300.      /* Get value */
  301.      CreateIcons = MatchToolValue(value, "YES");
  302.  
  303.     /* Free icon */
  304.     FreeDiskObject(dobj);
  305.     dobj = NULL;
  306.    }
  307.  
  308.    /* WB, read tool types from second icon */
  309.    if (wbs->sm_NumArgs > 1) {
  310.  
  311.     STARTUP_LOG(LOG1(WBArg, "0x%08lx", &wbs->sm_ArgList[1]))
  312.  
  313.     /* Go to projects directory */
  314.     CurrentDir(wbs->sm_ArgList[1].wa_Lock);
  315.  
  316.     /* Set configuration file name and get icon */
  317.     if (dobj = GetDiskObjectNew(config = wbs->sm_ArgList[1].wa_Name)) {
  318.  
  319.      STARTUP_LOG(LOG1(Icon, "0x%08lx", dobj))
  320.  
  321.      /* USE switch ? */
  322.      if (FindToolType(dobj->do_ToolTypes, "USE")) {
  323.  
  324.       STARTUP_LOG(LOG0(USE))
  325.  
  326.       /* Copy file to ENV: */
  327.       rc = CopyFile(config, ConfigUseName);
  328.  
  329.      /* SAVE switch? */
  330.      } else if (FindToolType(dobj->do_ToolTypes, "SAVE")) {
  331.  
  332.       STARTUP_LOG(LOG0(SAVE))
  333.  
  334.       /* Copy file to ENVARC: */
  335.       rc = CopyFile(config, ConfigSaveName);
  336.  
  337.      /* Default is EDIT switch */
  338.      } else
  339.       edit = TRUE;
  340.     }
  341.    } else
  342.  
  343.     /* No second icon, edit is default */
  344.     edit = TRUE;
  345.  
  346.   } else {
  347.  
  348.    /* CLI, read command line parameters */
  349.    if (rda = ReadArgs(Template, (LONG *) &CmdLineParameters, NULL)) {
  350.  
  351.     STARTUP_LOG(LOG1(Command line, "0x%08lx", rda))
  352.  
  353.     /* Set configuration file name if specified */
  354.     if (CmdLineParameters.From) config = CmdLineParameters.From;
  355.  
  356.     /* USE switch? */
  357.     if (CmdLineParameters.Use) {
  358.  
  359.      STARTUP_LOG(LOG0(USE))
  360.  
  361.      /* Copy file to ENV: */
  362.      rc = CopyFile(config, ConfigUseName);
  363.  
  364.     /* SAVE switch? */
  365.     } else if (CmdLineParameters.Save) {
  366.  
  367.      STARTUP_LOG(LOG0(SAVE))
  368.  
  369.      /* Copy file to ENVARC: */
  370.      rc = CopyFile(config, ConfigSaveName);
  371.  
  372.     /* Default is EDIT switch */
  373.     } else
  374.      edit        = TRUE;
  375.      CreateIcons = CmdLineParameters.Icons;
  376.    }
  377.   }
  378.  
  379.   /* Start editing? */
  380.   if (edit) {
  381.  
  382.    STARTUP_LOG(LOG0(Startup MUI application))
  383.  
  384.    /* Allocate minimum stack for a MUI application */
  385.    if (MUIStack.stk_Lower = AllocMem(STACKSIZE, MEMF_PUBLIC)) {
  386.  
  387.     STARTUP_LOG(LOG0(Stack allocated))
  388.  
  389.     /* Init stack swap structure */
  390.     MUIStack.stk_Upper   = (ULONG) MUIStack.stk_Lower + STACKSIZE;
  391.     MUIStack.stk_Pointer = (APTR)  MUIStack.stk_Upper;
  392.  
  393.     /* Swap stacks */
  394.     StackSwap(&MUIStack);
  395.  
  396.     /* Initialize locale */
  397.     InitLocale();
  398.  
  399.     /* Allocate resources */
  400.     if (GetEditResources()) {
  401.  
  402.      STARTUP_LOG(LOG0(Resources allocated))
  403.  
  404.      /* Allocate memory for program name */
  405.      if (ProgramName = CreateProgramName(wbs ? wbs->sm_ArgList : NULL)) {
  406.       Object *app, *win;
  407.  
  408.       STARTUP_LOG(LOG2(Program Name, "%s (0x%08lx)", ProgramName, ProgramName))
  409.  
  410.       if (app = ApplicationObject,
  411.                  MUIA_Application_Title,       "ToolManagerPrefs",
  412.                  MUIA_Application_Version,     Version,
  413.                  MUIA_Application_Copyright,   TMCOPYRIGHTYEAR ", Stefan Becker",
  414.                  MUIA_Application_Author,      "Stefan Becker",
  415.                  MUIA_Application_Description, TextGlobalTitle,
  416.                  MUIA_Application_Base,        "TOOLMANAGER",
  417.                  MUIA_Application_HelpFile,    "ToolManager.guide",
  418.                  MUIA_Application_SingleTask,
  419. #ifdef DEBUG
  420.                                                FALSE,
  421. #else
  422.                                                TRUE,
  423. #endif
  424.                  MUIA_Application_Window,      win =
  425.                   NewObject(MainWindowClass->mcc_Class, NULL,
  426.                  End,
  427.                  MUIA_HelpNode,                "Top",
  428.                 End) {
  429.        ULONG opened;
  430.  
  431.        STARTUP_LOG(LOG2(Application, "App 0x%08lx Win 0x%08lx", app, win))
  432.  
  433.        /* Initialize hook */
  434.        AppMessageHook.h_Data = win;
  435.  
  436.        /* Open main window */
  437.        SetAttrs(win, MUIA_Window_Open, TRUE, TAG_DONE);
  438.  
  439.        /* Get window open status */
  440.        GetAttr(MUIA_Window_Open, win, &opened);
  441.  
  442.        /* Window open? */
  443.        if (opened) {
  444.  
  445.         /* Reset return code */
  446.         rc = RETURN_OK;
  447.  
  448.         STARTUP_LOG(LOG0(Window opened))
  449.  
  450.         /* Tell main window to load configuration */
  451.         DoMethod(win, TMM_Load, config);
  452.  
  453.         STARTUP_LOG(LOG1(Configuration loaded, "%s", config))
  454.  
  455.         /* Event loop */
  456.         {
  457.          ULONG signals = 0;
  458.  
  459.          /* Handle application input */
  460.          while (DoMethod(app, MUIM_Application_NewInput, &signals)
  461.                 != MUIV_Application_ReturnID_Quit) {
  462.  
  463. #if DEBUG_VERY_NOISY
  464.           /* This just generates too much debug output... */
  465.           STARTUP_LOG(LOG1(Signals, "0x%08lx", signals))
  466. #endif
  467.  
  468.           /* Got any signals to wait for? Yes, then wait for them */
  469.           if (signals &&
  470.               (Wait(SIGBREAKF_CTRL_C | signals) & SIGBREAKF_CTRL_C))
  471.  
  472.            /* Got CTRL-C, leave loop */
  473.            break;
  474.          }
  475.         }
  476.  
  477.         STARTUP_LOG(LOG0(Leaving))
  478.  
  479.         /* Close main window */
  480.         SetAttrs(win, MUIA_Window_Open, FALSE, TAG_DONE);
  481.  
  482.         /* Remove main window object from application */
  483.         DoMethod(app, OM_REMMEMBER, win);
  484.  
  485.         /* Dispose main window object (deletes all attached objects) */
  486.         MUI_DisposeObject(win);
  487.        }
  488.  
  489.        /* Delete application */
  490.        MUI_DisposeObject(app);
  491.       }
  492.  
  493.       /* Free program name buffer */
  494.       FreeVector(ProgramName);
  495.      }
  496.     }
  497.  
  498.     /* Free resources */
  499.     FreeEditResources();
  500.  
  501.     /* Remove locale */
  502.     DeleteLocale();
  503.  
  504.     /* Swap back to original stack */
  505.     StackSwap(&MUIStack);
  506.  
  507.     /* Free stack */
  508.     FreeMem(MUIStack.stk_Lower, STACKSIZE);
  509.    }
  510.   }
  511.  
  512.   /* Free icon */
  513.   if (dobj) FreeDiskObject(dobj);
  514.  
  515.   /* Started from Workbench? Go back to old directory */
  516.   if (wbs) CurrentDir(oldcd);
  517.  
  518.   /* Free command line arguments */
  519.   if (rda) FreeArgs(rda);
  520.  
  521.   /* Error? */
  522.   if (rc != RETURN_OK)
  523.  
  524.    /* Inform the user */
  525.    EasyRequestArgs(NULL, &ErrorRequester, NULL, NULL);
  526.  
  527.   /* Close rest of the libraries */
  528.   CloseLibraries();
  529.  }
  530.  
  531.  STARTUP_LOG(LOG1(Result, "%ld", rc))
  532.  
  533.  /* Workbench startup message valid? */
  534.  if (wbs) {
  535.  
  536.   /* Yes, disable multitasking */
  537.   Forbid();
  538.  
  539.   /* Reply message */
  540.   ReplyMsg((struct Message *) wbs);
  541.  }
  542.  
  543.  return(rc);
  544. }
  545.